package crmdna.user;

import java.util.List;
import java.util.Set;

import crmdna.client.Client;
import crmdna.common.APIException;
import crmdna.common.APIResponse.Status;
import crmdna.common.Utils;
import crmdna.group.Group;
import crmdna.user.UserCore.UserProp;

public class User {

	public enum ResourceType {
		MEMBER, GROUP, USER, INTERACTION, PRACTICE, PROGRAM_TYPE, VENUE, TEACHER, PROGRAM, CUSTOM_CONFIG, PAYPAL_CREDENTIALS, EMAIL_CONFIG, CONFIG, INVENTORY_ITEM_TYPE, INVENTORY_ITEM, DEPARTMENT, LIST 
	}

	public enum Action {
		READ, WRITE, READWRITE, BULKWRITE, PURGEALL, UPDATE_QUANTITY
	}

	public static final String SUPER_USER = "sathyanarayanant@gmail.com";

	public static UserProp create(String client, String email, long groupId,
			String login) {
		Client.ensureValid(client);
		User.ensureAccess(client, login, ResourceType.USER, 0, Action.WRITE);
		Group.safeGet(client, groupId);

		return UserCore.create(client, email, groupId);
	}

	public static UserProp updateEmail(String client, String existingEmail,
			String newEmail, String login) {

		Client.ensureValid(client);
		User.ensureAccess(client, login, ResourceType.USER, 0, Action.WRITE);

		UserProp userProp = UserCore.updateEmail(client, existingEmail,
				newEmail);
		return userProp;
	}

	public static UserProp updateGroup(String client, String email,
			long newGroupId, String login) {

		Client.ensureValid(client);
		User.ensureAccess(client, login, ResourceType.USER, 0, Action.WRITE);
		Group.safeGet(client, newGroupId);

		return UserCore.updateGroup(client, email, newGroupId);
	}

	public static UserEntity get(String client, String email) {

		Client.ensureValid(client);
		return UserCore.get(client, email);
	}

	public static UserEntity safeGet(String client, String email) {

		Client.ensureValid(client);
		return UserCore.safeGet(client, email);
	}

	public static List<UserProp> getAll(String client) {

		Client.ensureValid(client);
		return UserCore.getAll(client);
	}

	public static List<UserProp> getAllForGroup(String client, long groupId) {
		Client.ensureValid(client);
		return UserCore.getAllForGroup(client, groupId);
	}

	public static UserProp addOrDeletePrivilege(String client, String email,
			ResourceType resourceType, long resourceId, Action action,
			boolean add, String login) {

		Client.ensureValid(client);
		User.ensureAccess(client, login, ResourceType.USER, 0, Action.WRITE);

		UserProp userProp = UserCore.addOrDeletePrivilege(client, email,
				resourceType.toString(), resourceId, action.toString(), add);
		return userProp;
	}

	public static UserProp clonePrivileges(String client, String sourceEmail,
			String targetEmail, String login) {

		Client.ensureValid(client);
		ensureAccess(client, login, ResourceType.USER, 0, Action.WRITE);

		UserProp userProp = UserCore.clonePrivileges(client, sourceEmail,
				targetEmail);
		return userProp;
	}

	public static void ensureValidUser(String client, String login) {

		Client.ensureValid(client);
		UserCore.ensureValidUser(client, login);
	}

	public static void ensureAccess(String client, String login,
			ResourceType resourceType, long resourceId, Action action) {

		Client.ensureValid(client);

		if ((null == login) || login.equals(""))
			throw new APIException(Status.ERROR_LOGIN_REQUIRED,
					"Email cannot be null or empty");

		if (null == resourceType)
			Utils.throwIncorrectSpecException("resourceType cannot be null");

		if (null == action)
			Utils.throwIncorrectSpecException("action cannot be null");

		UserCore.ensureAccess(client, login, resourceType.toString(),
				resourceId, action.toString());
	}

	public static Set<Long> getResources(String client, String login,
			ResourceType resourceType, Action action) {

		Client.ensureValid(client);

		if (null == resourceType)
			Utils.throwIncorrectSpecException("resourceType cannot be null");

		if (null == action)
			Utils.throwIncorrectSpecException("action cannot be null");

		return UserCore.getResources(client, login, resourceType.toString(),
				action.toString());

	}
}